package com.whosly.disclosure.early.handler.autoconfig.auto;

import com.whosly.disclosure.early.handler.DingtalkErrorHandler;
import com.whosly.disclosure.early.handler.DingtalkProperties;
import com.whosly.disclosure.early.handler.LogErrorHandler;
import com.whosly.disclosure.early.handler.LogProperties;
import com.whosly.disclosure.early.handler.infra.yaml.YamlEngine;
import com.whosly.disclosure.early.handler.spi.ErrorHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.InputStream;

@Configuration(proxyBeanMethods = false)
//@ConditionalOnClass(DingtalkErrorHandler.class)
@EnableConfigurationProperties({DingtalkProperties.class, LogProperties.class})
@Slf4j
public class AutoConfiguration implements InitializingBean {
    /**
     * 存在 `spring.whosly.disclosure.type` 配置且配置值为 dingtalk， 则加载.
     *
     * @param dingtalkProperties
     * @return
     */
    @Bean
    @ConditionalOnProperty(prefix = "spring.whosly.disclosure", name = "type", havingValue = "dingtalk")
    public ErrorHandler errorHandlerDingtalk(DingtalkProperties dingtalkProperties) {
        log.debug("AutoConfiguration errorHandlerDingtalk:{} .", dingtalkProperties);

        // 如果配置在 spring 中未加载，则读取配置路径
        if (null == dingtalkProperties || StringUtils.isEmpty(dingtalkProperties.getWebhook())) {
            synchronized (this) {
                if (null == dingtalkProperties || StringUtils.isEmpty(dingtalkProperties.getWebhook())) {
                    log.info("DingtalkProperties create default ...");

                    InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(DingtalkErrorHandler.ERROR_HANDLER_CONFIG);
                    dingtalkProperties = YamlEngine.unmarshal(DingtalkErrorHandler.CONFIG_YAML_PREFIX, inputStream, DingtalkProperties.class);
                }
            }
        }

        DingtalkErrorHandler handler = new DingtalkErrorHandler(dingtalkProperties);

        return handler;
    }

    /**
     * 存在 `spring.whosly.disclosure.type` 配置且配置值为 log， 且无 errorHandlerDefault 配置。则加载.
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(name = "errorHandlerDefault")
    @ConditionalOnProperty(prefix = "spring.whosly.disclosure", name = "type", havingValue = "log")
    public ErrorHandler errorHandlerLog(LogProperties logProperties) {
        log.debug("AutoConfiguration errorHandlerLog ...");

        if(logProperties == null){
            synchronized (this) {
                if(logProperties == null){
                    log.info("LogProperties create default ...");
                    logProperties = new LogProperties();
                }
            }
        }

        ErrorHandler handler = new LogErrorHandler(logProperties);
        return handler;
    }

    /**
     * 不存在 `spring.whosly.disclosure.type` 配置， 且无 ErrorHandler.class 配置。则加载.
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(value = ErrorHandler.class)
    @ConditionalOnProperty(prefix = "spring.whosly.disclosure", name = "type", matchIfMissing = true)
    public ErrorHandler errorHandlerDefault(LogProperties logProperties) {
        log.debug("AutoConfiguration errorHandlerDefault ...");

        if(logProperties == null){
            synchronized (this) {
                if(logProperties == null){
                    log.info("LogPropertie's create default ...");
                    logProperties = new LogProperties();
                }
            }
        }

        ErrorHandler handler = new LogErrorHandler(logProperties);
        return handler;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.debug("AutoConfiguration init...");
    }
}
